package com.augurit.common.system.service.org.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;

import com.augurit.common.constant.OrgConstant;
import com.augurit.common.dao.AcModuleDao;
import com.augurit.common.entity.AcModule;
import com.augurit.common.syscode.service.ISysCodeService;
import com.augurit.common.syscode.web.form.SysCodeForm;
import com.augurit.common.system.convert.AcModuleConverter;
import com.augurit.common.system.service.org.IAcFunctionService;
import com.augurit.common.system.service.org.IAcModuleService;
import com.augurit.common.system.web.org.form.AcFunctionForm;
import com.augurit.common.system.web.org.form.AcModuleForm;
import com.augurit.common.util.PageUtils;
import com.augurit.common.util.lang.CollectionUtils;

/**
 * 菜单逻辑实现类
 */
@Service
@Transactional
public class AcModuleServiceImpl implements IAcModuleService {
	
	// DAO 引用
	@Autowired
	private AcModuleDao acModuleDao; //应用DAO类
	
	// 功能service
	@Autowired
	private IAcFunctionService acFunctionService;
	
	@Autowired
	private ISysCodeService syscodeService;
	

	/**
	 * 根据ID获取模块Form对象
	 * @param id 模块主键ID
	 * @return 模块Form对象
	 */
	@Transactional(readOnly = true)
	public AcModuleForm get(Long id){
		return acModuleDao.getForm(id);
	}
	
	/**
	 * 保存模块Form对象数组
	 * @param forms Form对象数组
	 */
	public void save(AcModuleForm... forms){
		if(forms != null){
			for(AcModuleForm form : forms)
				acModuleDao.save(form);
		}
	}

	/**
	 * 根据主键ID集合删除模块对象
	 * @param ids 模块主键ID集合
	 */
	public void delete(Long... ids) {
		if(ids != null)
			acModuleDao.delete(ids);
	}
	
	/**
	 * 根据应用主键ID查找该应用下的所有模块和子模块的ID集合
	 * @param appId 应用id
	 * @return 模块id数组
	 */
	@Transactional(readOnly = true)
	public Long[] getAllModuleIds(Long appId){
		return acModuleDao.getModuleIds(appId, false);
	}
	
	/**
	 * 根据应用的id找出它的所有模块及子模块
	 * @param appId 应用主键ID
	 * @return 模块form对象列表
	 */
	@Transactional(readOnly = true)
	public List<AcModuleForm> getAllModules(Long appId){
		List<AcModule> list = acModuleDao.getModules(appId, false);
		return AcModuleConverter.convertToFormList(list);
	}
	
	/**
	 * 分页获取指定应用的所有模块及子模块
	 * @param appId 应用ID
	 * @return 所有模块及子模块form对象列表
	 */
	@Transactional(readOnly = true)
	public Page<AcModuleForm> getAllModules(Long appId, Page<AcModuleForm> page){
		
		// 建立新的分页对象
		Page<AcModule> pg = PageUtils.newPageInstance(page);
		
		// 按过滤条件分页查找对象
		String hql = "from AcModule ps where ps.appId = ?";
		acModuleDao.findPage(pg, hql, appId);
		
		// 转换为Form对象列表并赋值到原分页对象中
		List<AcModuleForm> list = AcModuleConverter.convertToFormList(pg.getResult());
		PageUtils.copy(pg, list, page);
		
		return page;
	}
	
	/**
	 * 获取指定应用的直属模块的ID集合
	 * @param appId 应用ID
	 * @return 直属模块form对象列表
	 */
	@Transactional(readOnly = true)
	public Long[] getModuleIds(Long appId){
		return acModuleDao.getModuleIds(appId, true);
	}
	
	/**
	 * 获取指定应用的直属模块列表
	 * @param appId：应用主键ID
	 * @return 模块form对象列表
	 */
	@Transactional(readOnly = true)
	public List<AcModuleForm> getModules(Long appId){
		List<AcModule> list = acModuleDao.getModules(appId, true);
		return AcModuleConverter.convertToFormList(list);
	}
	
	/**
	 * 分页获取指定应用的直属模块列表
	 * @param appId 应用主键ID
	 * @return 包含模块form对象的分页对象
	 */
	@Transactional(readOnly = true)
	public Page<AcModuleForm> getModules(Long appId, Page<AcModuleForm> page, Map<String, List<SysCodeForm>> sysCodeBuffer){
		if(appId != null){
			// 建立新的分页对象
			Page<AcModule> pg = PageUtils.newPageInstance(page);
			
			// 按过滤条件分页查找对象
			String hql = "from AcModule ps where ps.moduleLevel=1 and ps.appId=?";
			pg = acModuleDao.findPage(pg, hql, appId);
			
			// 转换为Form对象列表并赋值到原分页对象中
			List<AcModuleForm> list = AcModuleConverter.convertToFormList(pg.getResult(),
					syscodeService.getItems(OrgConstant.SYS_CODE_MODULE_TYPE, sysCodeBuffer));
			PageUtils.copy(pg, list, page);
		}
		return page;
	}
	
	/**
	 * 获取指定父模块的所有子模块的ID集合
	 * @param parentModuleId 指定父模块ID
	 */
	@Transactional(readOnly = true)
	public Long[] getAllChildModuleIds(Long parentModuleId){
		return acModuleDao.getAllChildModuleIds(parentModuleId);
	}
	
	/**
	 * 获取指定父模块的所有子模块Form对象列表
	 * @param parentModuleId 指定父模块ID
	 * @return 包含模块form对象的分页对象
	 */
	@Transactional(readOnly = true)
	public List<AcModuleForm> getAllChildModules(Long parentModuleId){
		List<AcModule> list = acModuleDao.getAllChildModules(parentModuleId);
		return AcModuleConverter.convertToFormList(list);
	}
	
	/**
	 * 分页获取指定父模块的所有子模块Form对象列表
	 * @param parentModuleId 指定父模块ID
	 * @return 包含模块form对象的分页对象
	 */
	@Transactional(readOnly = true)
	public Page<AcModuleForm> getAllChildModules(Long parentModuleId, Page<AcModuleForm> page){
		// 建立新的分页对象
		Page<AcModule> pg = PageUtils.newPageInstance(page);
		
		// 按过滤条件分页查找对象
		String hql = "from AcModule ps where ps.moduleSeq like ? and ps.moduleId != ?";
		List values = new ArrayList();
		values.add("%." + parentModuleId + ".%");
		values.add(parentModuleId);
		pg = acModuleDao.findPage(pg, hql, values);
		
		// 转换为Form对象列表并赋值到原分页对象中
		List<AcModuleForm> list = AcModuleConverter.convertToFormList(pg.getResult());
		PageUtils.copy(pg, list, page);
		
		return page;
	}
	
	/**
	 * 获取指定父模块的直属模块的ID集合
	 * @param parentModuleId 指定父模块ID
	 * @return 模块id数组
	 */
	public Long[] getChildModuleIds(Long parentModuleId){
		return acModuleDao.getChildModuleIds(parentModuleId);
	}
	
	/**
	 * 获取指定父模块的直属模块列表
	 * @param parentModuleId 指定父模块ID
	 * @return 模块form对象列表
	 */
	@Transactional(readOnly = true)
	public List<AcModuleForm> getChildModules(Long parentModuleId, Map<String, List<SysCodeForm>> sysCodeBuffer){
		List<AcModule> list = acModuleDao.getChildModules(parentModuleId);
		return AcModuleConverter.convertToFormList(list,
				syscodeService.getItems(OrgConstant.SYS_CODE_MODULE_TYPE, sysCodeBuffer));
	}
	
	/**
	 * 分页获取指定父模块的直属模块Form对象列表
	 * @param parentModuleId 指定父模块ID
	 * @param page 分页对象
	 * @return 包含模块form对象的分页对象
	 */
	@Transactional(readOnly = true)
	public Page<AcModuleForm> getChildModules(Long parentModuleId, Page<AcModuleForm> page, Map<String, List<SysCodeForm>> sysCodeBuffer){
		// 建立新的分页对象
		Page<AcModule> pg = PageUtils.newPageInstance(page);
		
		// 按过滤条件分页查找对象
		String hql = "from AcModule ps where ps.parentModuleId=?";
		acModuleDao.findPage(pg, hql, parentModuleId);
		
		// 转换为Form对象列表并赋值到原分页对象中
		List<AcModuleForm> list = AcModuleConverter.convertToFormList(pg.getResult(),
				syscodeService.getItems(OrgConstant.SYS_CODE_MODULE_TYPE, sysCodeBuffer));
		PageUtils.copy(pg, list, page);
		
		return page;
	}
	
	/**
	 * 找出模块下直属的功能点
	 * @param moduleId：模块主键
	 * @return:返回模块下直属功能form列表
	 */
	@Transactional(readOnly = true)
	public List<AcFunctionForm> getFuncs(Long moduleId){
		return acFunctionService.getFuncsByModuleId(moduleId);
	}
	
	/**
	 * 获取模块列表下的直属功能列表
	 * @param moduleIds 模块列表id
	 * @return 模块列表下的所有模块的直属功能集合的列表
	 */
	@Transactional(readOnly = true)
	public List<AcFunctionForm> getFuncs(Long[] moduleIds) {
		return acFunctionService.getFuncsByModuleIds(moduleIds);
	}

	/**
	 * 找出模块下所有的功能点，包括其子模块下的功能点
	 * @param moduleId：模块主键
	 * @return：返回模块下所有的功能form列表
	 */
	@Transactional(readOnly = true)
	public List<AcFunctionForm> getAllFuncs(Long moduleId){
		
		if(moduleId != null){
			List<AcFunctionForm> funcList = acFunctionService.getFuncsByModuleId(moduleId);
			
			Long[] moduleIds = acModuleDao.getAllChildModuleIds(moduleId);
			if(moduleIds != null){
				for(Long id : moduleIds){
					List<AcFunctionForm> childList = acFunctionService.getFuncsByModuleId(id);
					funcList.addAll(childList);
				}
			}
			
			return funcList;
		}else
			return null;
	}
	
	/**
	 * 获取模块下的直属模块及功能列表
	 * @param mouduleId
	 * @return 模块form对象
	 */
	public AcModuleForm getModuleRelatedElements(Long moduleId, Map<String, List<SysCodeForm>> sysCodeBuffer){
		if(moduleId != null){
			AcModuleForm form = new AcModuleForm();
			form.setChildren(this.getChildModules(moduleId, sysCodeBuffer));
			form.setFunctions(this.getFuncs(moduleId));
			return form;
		}
		return null;
	}
	
	/**
	 * 获取父模块id
	 * @param moduleId 模块id
	 * @return 父模块id
	 */
	public Long getParentModuleId(Long moduleId){
		return acModuleDao.getParentModuleId(moduleId);
	}
	
	/**
	 * 获取父模块form对象
	 * @param moduleId 模块id
	 * @return 模块form对象
	 */
	public AcModuleForm getParentModule(Long moduleId){
		return acModuleDao.getParentModule(moduleId);
	}
	
	/**
	 * 添加模块
	 * @param form 模块对象
	 */
	public void addModuleCascade(AcModuleForm form){
		acModuleDao.addModuleCascade(form);
	}
	
	/**
	 * 删除指定模块的直属功能
	 * @param moduleId 模块主键ID
	 */
	private void deleteFuncs(Long moduleId){
		List<Long> funcIds = acFunctionService.getFuncIdsByModuleId(moduleId);
		acFunctionService.deleteFuncCascade(CollectionUtils.toLongArray(funcIds));
	}

	/**
	 * 根据模块主键ID级联删除模块
	 * 主要流程：由于模块中包含子模块
	 *   1：删除该模块：操作AC_MODULE：操作AC_MODULE
	 *   2：删除该模块下的所有的功能点：删除AC_FUNCTION
	 *   3：删除该模块下的所有子模块（相当与找出以该结点为树根的整棵树）
	 * @param id 模块的主键ID
	 */
	public void deleteModuleCascade(Long... moduleIds){
		if(moduleIds != null){
			for (Long moduleId : moduleIds) {
				// 删除指定模块的所有子模块
				deleteAllChildModules(moduleId);
				
				// 删除指定模块的直属功能
			    deleteFuncs(moduleId);
				
				// 更新被删除模块的父模块数据
			    Long parentModuleId = acModuleDao.get(moduleId).getParentModuleId();
				acModuleDao.updateModuleAfterRemoveChildren(parentModuleId);
				
				// 删除指定模块本身
				delete(moduleId);
			}
		}
	}
	
	/**
	 * 删除指定模块的所有子模块
	 * @param moduleId 主键ID
	 */
	private void deleteAllChildModules(Long parentModuleId){
		if(parentModuleId != null){ 
			
			//获取所有子模块
			List<AcModule> children = acModuleDao.getAllChildModules(parentModuleId);
			
			for(AcModule module : children){
				
				//删除模块关联功能
				deleteFuncs(module.getModuleId());
				
				//删除模块本身
				delete(module.getModuleId());
			}
		}
	}
	
	/**
	 * 获取指定模块所属的应用的id
	 * @param moduleId:模块id
	 * @return:指定模块所属应用的id
	 */
	public Long getAppId(Long moduleId){
		if(moduleId != null){	
			AcModule entity = acModuleDao.get(moduleId);
			if(entity != null)
				return entity.getAppId();
		}
		return null;
	}

	
}
